﻿using System;
using System.Collections.Generic;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Text;
using Android.Views;
using Android.Views.InputMethods;
using Android.Widget;
using Xamarin.ActionbarSherlockBinding.App;
using Cinemacenter.Shared;

namespace Cinemacenter.Droid
{
	public class MarqueeFragment : SherlockListFragment, ITextWatcher
	{
		public static string CityIdNumber = "cityId";
		public static string TsvtNumber = "tsvt";
		public int CityId;
		public long MarqueeTsvt;
		List<Movie> filterArray = new List<Movie> ();
		Marquee movies;
		EditText mySearch;
		View emptySearchResults;
		Xamarin.ActionbarSherlockBinding.App.ActionBar actionBar;
		IMarqueeFragmentCallbacks mCallbacks;

		public interface IMarqueeFragmentCallbacks
		{
			void NotifyOnMarqueeLoaded (Marquee dataset);

			void NotifyMarqueeHasItems (bool hasItems);

			void NotifyOnMarqueeLoadFailed ();
		}

		public override void OnAttach (Activity activity)
		{
			base.OnAttach (activity);
			mCallbacks = (IMarqueeFragmentCallbacks)activity;
			actionBar = ((SherlockFragmentActivity)activity).SupportActionBar;
		}

		public override void OnCreate (Bundle savedInstanceState)
		{
			base.OnCreate (savedInstanceState);
			HasOptionsMenu = true;
			RetainInstance = true;
			CityId = Arguments.GetInt (CityIdNumber);
			MarqueeTsvt = Arguments.GetLong (TsvtNumber);
		}


		public override View OnCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
		{
			var movieListView = inflater.Inflate (Resource.Layout.ViewMovieList, container, false);
			emptySearchResults = Activity.FindViewById<View> (Resource.Id.search_empty_tv);
			return movieListView;
		}

		public override void OnViewCreated (View view, Bundle savedInstanceState)
		{
			base.OnViewCreated (view, savedInstanceState);
			ListView.SetDrawSelectorOnTop (true);
			ListView.ItemClick += (s, e) => {
				var movieId = ((MovieAdapter)ListAdapter).Movies [e.Position].ID;
				OpenDetailActivity (movieId);
			};

			if (ListAdapter == null) {
				ListAdapter = new MovieAdapter (view.Context);
				GetData ();
			}
		}

		public void SetAdapter (List<Movie> items)
		{
			if (null != items && items.Count != 0) {
				emptySearchResults.Visibility = ViewStates.Gone;
			} else {
				if ((mySearch != null) && (mySearch.Text.Length > 0))
					emptySearchResults.Visibility = ViewStates.Visible;
			}
			var adapter = (MovieAdapter)ListAdapter;
			adapter.Movies = items;
			adapter.NotifyDataSetChanged ();
		}

		public override void OnCreateOptionsMenu (Xamarin.ActionbarSherlockBinding.Views.IMenu menu, Xamarin.ActionbarSherlockBinding.Views.MenuInflater inflater)
		{
			inflater.Inflate (Resource.Menu.search, menu);
			var menuSearch = menu.FindItem (Resource.Id.menu_search);
			mySearch = (EditText)menuSearch.ActionView;
			mySearch.AddTextChangedListener (this);
			menuSearch.SetOnActionExpandListener (new SearchViewExpandListener (mySearch));
			base.OnCreateOptionsMenu (menu, inflater);
		}

		public async void GetData ()
		{
			long unixTime = new DateTime ().CurrentTimeMillis () / 1000L;
			movies = new Marquee ();
			movies.Movies = DBHelper.GetMovies ();
			if (unixTime > MarqueeTsvt || movies.Movies.Count == 0) {
				using (var progress = new ProgressDialog (Activity)) {
					progress.SetMessage (GetString (Resource.String.loading));
					progress.SetCanceledOnTouchOutside (false);
					progress.SetTitle (actionBar.Title);
					progress.Show ();
					movies = await WebService.Shared.GetMovies (CityId);
					if (movies.Movies == null) {
						movies.Movies = new List<Movie> ();
						mCallbacks.NotifyOnMarqueeLoadFailed ();
						movies.Movies = DBHelper.GetMovies ();
					} else {
						mCallbacks.NotifyOnMarqueeLoaded (movies);
						DBHelper.DeleteMovies ();
						DBHelper.SaveMovies (movies.Movies);
					}
					progress.Dismiss ();
				}
			}
			mCallbacks.NotifyMarqueeHasItems (movies.Movies.Count > 0);
			SetAdapter (movies.Movies);
			if (Activity.Intent.Data != null)
				OpenMovieFromUri (Activity.Intent.Data);
		}

		void OpenMovieFromUri (Android.Net.Uri uri)
		{
			foreach (var movie in DBHelper.GetMovies ())
				if (movie.Link.Contains (uri.ToString ()))
					OpenDetailActivity (movie.ID);
		}

		void OpenDetailActivity (int movieId)
		{
			var intent = new Intent ();
			intent.SetClass (Activity, typeof(DetailsActivity));
			intent.PutExtra ("movieId", movieId);
			intent.AddFlags (ActivityFlags.NoAnimation);
			StartActivity (intent);
		}

		void ITextWatcher.AfterTextChanged (IEditable s)
		{
			filterArray.Clear ();
			var searchString = mySearch.Text.Trim ().ToLower ();
			if ((movies != null) && (movies.Movies != null)) {
				if ((movies.Movies.Count > 0) && (!string.IsNullOrEmpty (searchString))) {
					foreach (var movie in movies.Movies) {
						if (!string.IsNullOrEmpty (movie.Name) && movie.Name.ToLower ().Contains
							(searchString.ToLower ())) {
							filterArray.Add (movie);
						}
					}
					SetAdapter (filterArray);
				} else {
					filterArray.Clear ();
					SetAdapter (movies.Movies);
				}
			}
		}

		void ITextWatcher.BeforeTextChanged (Java.Lang.ICharSequence s, int start, int count, int after)
		{
		}

		void ITextWatcher.OnTextChanged (Java.Lang.ICharSequence s, int start, int before, int count)
		{
		}

		public class SearchViewExpandListener : Java.Lang.Object, Xamarin.ActionbarSherlockBinding.Views.IMenuItemOnActionExpandListener
		{
			readonly EditText t;

			public SearchViewExpandListener (EditText t)
			{
				this.t = t;
			}

			public bool OnMenuItemActionCollapse (Xamarin.ActionbarSherlockBinding.Views.IMenuItem item)
			{
				t.Text = string.Empty;
				t.ClearFocus ();
				var imm = (InputMethodManager)t.Context.GetSystemService (Context.InputMethodService);
				imm.HideSoftInputFromWindow (t.WindowToken, 0); 
				return true;
			}

			public bool OnMenuItemActionExpand (Xamarin.ActionbarSherlockBinding.Views.IMenuItem item)
			{
				t.RequestFocus ();
				var imm = (InputMethodManager)t.Context.GetSystemService (Context.InputMethodService);
				imm.ToggleSoftInput (ShowFlags.Forced, 0);
				return true;
			}
		}
	}
}